AddCSLuaFile( "cl_init.lua" )
AddCSLuaFile( "shared.lua" )
include('shared.lua')

function ENT:Initialize()	
	self.Entity:PhysicsInit( SOLID_VPHYSICS )
	self.Entity:SetMoveType( MOVETYPE_VPHYSICS )
	self.Entity:SetSolid( SOLID_VPHYSICS )
	
	self.Inputs = CDE_Wire_CreateInputs(self.Entity, { "Fire" })
	self.Outputs = CDE_Wire_CreateOutputs(self.Entity, { "Can Fire" , "Cooldown Time" })
	
	CDE_RD_AddResource(self, "energy", 0)
	self.Entity:NextThink(CurTime())
	
	self.PrintName = self.DamageType .. " " .. self.PrintName
	self.NextReady = CurTime()
	self.Entity:SetNetworkedString( "GModOverlayText", self.PrintName )
	self.WireDebugName = self.PrintName
end

function ENT:TriggerInput(k,v)
	if (k == "Fire") then
		self.Firing = util.tobool(v)
	end
end

function ENT:BeamFireCalculate(origin, targetvector)
	origin = origin or self.Entity:LocalToWorld(self.Entity:OBBCenter())
	targetvector = targetvector or self.Entity:FireDirection()
	local trace = {}
	trace.start = origin
	trace.endpos = origin + targetvector * 60000
	trace.filter = self.Entity
	local traceresult = util.TraceLine(trace)
	local l_tracevec = traceresult.HitPos - origin
	local shieldsinplay = ents.FindByClass("shield_dome")
	local shieldsaffected = {}
	for _,shield in pairs(shieldsinplay) do
		if CDamage_checkshieldintersect(origin, targetvector, nil --[[self.Entity:GetPlayer()]], shield) then
			table.insert(shieldsaffected, shield)
		end
	end
	local hitentity = traceresult.Entity
	local hitposition = traceresult.HitPos
	local isshield = false
	for _,shield in pairs(shieldsaffected) do
		local hitpoint = CDamage_shieldintersectpoint(origin, targetvector, shield)
		if (CDamage_Vector_Compare(hitposition - origin, hitpoint - origin) > 0) then
			hitentity = shield
			hitposition = hitpoint
			isshield = true
		end
	end
	return hitentity, hitposition, isshield
end

function ENT:ToggleFireState()
	self.Firing = !self.Firing
end

function ENT:Think()
	--self.BaseClass.Think(self)
	if self.Firing and (CurTime() >= self.NextReady) and (CDE_RD_GetResourceAmount(self.Entity, "energy", true) >= self.EnergyDraw) then
		self.Entity:FireBeam()
		CDE_RD_ConsumeResource(self.Entity, "energy", self.EnergyDraw, true)
		self.Entity:EmitSound(Sound("CDE/red.wav"),90,math.random(90,110));
		self.NextReady = CurTime() + self.Cooldown
	end
	local canfire
	if (CurTime() >= self.NextReady) then canfire = 1 else canfire = 0 end
	CDE_Wire_TriggerOutput(self.Entity, "Can Fire", canfire)
	CDE_Wire_TriggerOutput(self.Entity, "Cooldown Time", math.Clamp(self.NextReady - CurTime(), 0, self.Cooldown))
	self.Entity:NextThink(CurTime() + 0.25)
	return true
end

function ENT:FireBeam()
	local hitentity, hitposition, isshield = self.Entity:BeamFireCalculate()
	CDamage_damageent(hitentity, self.Damage, nil, self.DamageType)
	if isshield then
		hitentity:Impact(hitposition, self.Damage)
	elseif util.tobool(self.Entity.blastradius) then
		CDamage_blastdamage(hitposition, self.Entity.blastradius, self.Entity.Damage, nil, false, self.Entity.DamageType)
	end
	self.Entity:DrawBeam(hitposition, hitentity)
end

function ENT:Touch( ent )
	if ent.HasHardpoints then
		if ent.Cont && ent.Cont:IsValid() then HPLink( ent.Cont, ent.Entity, self.Entity ) end
	end
end